<head>
  <style>
    body { margin: 0; }

    #time-log {
      position: absolute;
      font-size: 12px;
      font-family: sans-serif;
      padding: 5px;
      border-radius: 3px;
      background-color: rgba(200, 200, 200, 0.1);
      color: lavender;
      bottom: 10px;
      right: 10px;
    }
  </style>

  <script src="//cdn.jsdelivr.net/npm/globe.gl"></script>
<!--  <script src="../../dist/globe.gl.js"></script>-->
</head>

<body>
  <div id="chart"></div>
  <div id="time-log"></div>

  <script type="module">
    import * as satellite from 'https://esm.sh/satellite.js';

    const EARTH_RADIUS_KM = 6371; // km
    const TIME_STEP = 3 * 1000; // per frame

    const timeLogger = document.getElementById('time-log');

    const world = new Globe(document.getElementById('chart'))
      .globeImageUrl('//cdn.jsdelivr.net/npm/three-globe/example/img/earth-blue-marble.jpg')
      .particleLat('lat')
      .particleLng('lng')
      .particleAltitude('alt')
      .particlesColor(() => 'palegreen');

    setTimeout(() => world.pointOfView({ altitude: 3.5 }));

    fetch('../datasets/space-track-leo.txt').then(r => r.text()).then(rawData => {
      const tleData = rawData.replace(/\r/g, '')
        .split(/\n(?=[^12])/)
        .filter(d => d)
        .map(tle => tle.split('\n'));
      const satData = tleData.map(([name, ...tle]) => ({
        satrec: satellite.twoline2satrec(...tle),
        name: name.trim().replace(/^0 /, '')
      }))
      // exclude those that can't be propagated
      .filter(d => !!satellite.propagate(d.satrec, new Date())?.position);

      // time ticker
      let time = new Date();
      (function frameTicker() {
        requestAnimationFrame(frameTicker);

        time = new Date(+time + TIME_STEP);
        timeLogger.innerText = time.toString();

        // Update satellite positions
        const gmst = satellite.gstime(time);
        satData.forEach(d => {
          const eci = satellite.propagate(d.satrec, time);
          if (eci.position) {
            const gdPos = satellite.eciToGeodetic(eci.position, gmst);
            d.lat = satellite.radiansToDegrees(gdPos.latitude);
            d.lng = satellite.radiansToDegrees(gdPos.longitude);
            d.alt = gdPos.height / EARTH_RADIUS_KM
          }
        });

        world.particlesData([satData.filter(d => !isNaN(d.lat) && !isNaN(d.lng) && !isNaN(d.alt))]);
      })();
    });
  </script>
</body>